import { decryptByDESModeEBC, encryptByDESModeEBC } from '@/common/encrypt';
import http from '@/common/http';
import Utils from '@/common/pakjUtils';
import weixin from '@/common/weixinUtils';
import Config from '@/common/config';
import { Dialog, Toast } from 'mand-mobile';
import { GET_CAPTCHA, GET_CURRENT_LOCATION, LOGIN } from './actions.types';
import {
  SET_PLATFORM_ID,
  GET_CAPTCHA_FAILED,
  GET_CAPTCHA_SUCCESS,
  GET_CURRENT_LOCATION_SUCCESS,
  LOGIN_SUCCESS
} from './mutations.types';
import { GPS_UNKNOWN, GPS_LOCATING, GPS_SUCCESS, GPS_ERROR } from './gps.types';
import Loading from '@/components/loading';
import router from '@/router';
const CAPTCHA_MODE = 'captcha';
const PASSWORD_MODE = 'password';
var CryptoJS = require('crypto-js');
const defaultState = () => {
  return {
    user: undefined,
    isLogin: false,
    token: undefined,
    openId: undefined,
    unionId: undefined,
    phone: '',
    captcha: '',
    loginMode: CAPTCHA_MODE,
    currentLocation: {
      provinceCode: '110000',
      provinceName: '北京市',
      coordinate: [116.397428, 39.90923],
      address: '北京市东城区东华门街道天安门',
      city: '北京市'
    },
    gpsStatus: GPS_UNKNOWN
  };
};
const state = defaultState();
const getters = {
  currentUser(state) {
    if (!state.user) {
      let str = localStorage.getItem('USER_INFO');
      if (str) {
        state.user = JSON.parse(str);
        state.token = state.user.token;
      }
    }
    return state.user;
  },
  getPlatformId(state) {
    return state.platformId;
  },
  isLogin(state) {
    return state.isLogin;
  },
  getToken(state) {
    let tk = router.currentRoute.query.tk;
    if (tk) {
      return tk;
    }
    return state.token;
  },
  getOpenId(state) {
    return state.openId;
  },
  getUnionId(state) {
    return state.unionId;
  },
  currentPhone(state) {
    return state.phone;
  },
  currentCaptcha(state) {
    return state.captcha;
  },
  getCurrentLocation(state) {
    return state.currentLocation;
  },
  gpsStatus(state) {
    return state.gpsStatus;
  },
  loginMode(state) {
    return state.loginMode;
  }
};
const actions = {
  [LOGIN](context, params) {
    let loginUrl = params.url;
    delete params.url;
    // 发送登录请求
    let data = {};
    Object.assign(data, params); // 复制操作，防止操作原数据
    data.user_phone = encryptByDESModeEBC(params.user_phone);
    data.user_pwd = CryptoJS.MD5(params.password).toString();
    let openid = context.getters.getOpenId;
    if (openid) {
      data.openId = openid;
    }
    return new Promise((resolve, reject) => {
      Loading.show();
      http.post(loginUrl, data).then(res => {
        Loading.hide();
        if (res.data.code === '000000') {
          context.commit(LOGIN_SUCCESS, res.data.data);
          resolve(res.data.data);
        } else if (res.data.code === '200021') {
          // 密码登录未注册
          reject(new Error(res.data.code + ':' + res.data.msg));
        } else if (res.data.code === '100099') {
          // 账号被锁定
          reject(new Error(res.data.code));
          sessionStorage['loginerror'] = res.data.msg;
        } else if (res.data.code === '200020') {
          // 密码登录未设置登录密码
          reject(new Error(res.data.code + ':' + res.data.msg));
        } else if (res.data.code === '200025') {
          Toast({
            content: res.data.msg,
            duration: 3000,
            hasMask: true
          });
          reject(new Error(res.data.msg));
        } else if (res.data.code === '100001') {
          Toast({
            content: res.data.msg,
            duration: 3000,
            hasMask: true
          });
          reject(new Error(res.data.msg));
        } else {
          Dialog.alert({
            title: '提示',
            content: res.data.msg,
            confirmText: '确定'
          });
          reject(new Error(res.data.code + ':' + res.data.msg));
        }
      });
    });
  },
  hitchDriverLogin(context, params) {
    return new Promise((resolve, reject) => {
      Loading.show();
      http.post('/pakj/wexin/login', params).then(res => {
        Loading.hide();
        if (res.data.code === '000000') {
          context.commit('sethitchDriverLoginInfo', res.data.data);
          resolve();
        } else {
          reject(new Error(res.data.msg));
        }
      });
    });
  },
  wxLogin(context) {
    return new Promise((resolve, reject) => {
      Loading.show();
      http.post('/pakj/wexin/miniGetUserInfo').then(res => {
        Loading.hide();
        if (res.data.code === '000000') {
          context.commit(LOGIN_SUCCESS, res.data.data);
          resolve(res.data.data);
        } else if (res.data.code === '200021') {
          // 密码登录未注册
          reject(new Error(res.data.code + ':' + res.data.msg));
        } else if (res.data.code === '100099') {
          // 账号被锁定
          reject(new Error(res.data.code));
          sessionStorage['loginerror'] = res.data.msg;
        } else if (res.data.code === '200020') {
          // 密码登录未设置登录密码
          reject(new Error(res.data.code + ':' + res.data.msg));
        } else if (res.data.code === '200025') {
          Toast({
            content: res.data.msg,
            duration: 3000,
            hasMask: true
          });
          reject(new Error(res.data.msg));
        } else if (res.data.code === '100001') {
          Toast({
            content: res.data.msg,
            duration: 3000,
            hasMask: true
          });
          reject(new Error(res.data.msg));
        } else {
          Dialog.alert({
            title: '提示',
            content: res.data.msg,
            confirmText: '确定'
          });
          reject(new Error(res.data.code + ':' + res.data.msg));
        }
      });
    });
  },
  wxReg(context, params) {
    return new Promise((resolve, reject) => {
      let data = {};
      Object.assign(data, params);
      data.userPhone = encryptByDESModeEBC(params.userPhone);
      http.post('/pakj/wexin/miniProgramReg', data).then(res => {
        Loading.hide();
        if (res.data.code === '000000') {
          context.commit(LOGIN_SUCCESS, res.data.data);
          resolve(res.data.data);
        } else if (res.data.code === '200021') {
          // 密码登录未注册
          reject(new Error(res.data.code + ':' + res.data.msg));
        } else if (res.data.code === '100099') {
          // 账号被锁定
          reject(new Error(res.data.code));
          sessionStorage['loginerror'] = res.data.msg;
        } else if (res.data.code === '200020') {
          // 密码登录未设置登录密码
          reject(new Error(res.data.code + ':' + res.data.msg));
        } else if (res.data.code === '200025') {
          Toast({
            content: res.data.msg,
            duration: 3000,
            hasMask: true
          });
          reject(new Error(res.data.msg));
        } else if (res.data.code === '100001') {
          Toast({
            content: res.data.msg,
            duration: 3000,
            hasMask: true
          });
          reject(new Error(res.data.msg));
        } else {
          Dialog.alert({
            title: '提示',
            content: res.data.msg,
            confirmText: '确定'
          });
          reject(new Error(res.data.code + ':' + res.data.msg));
        }
      });
    });
  },
  wxAuth(context, code) {
    return new Promise((resolve, reject) => {
      let params = {
        code: code
      };
      Loading.show();
      http
        .post('pakj/wexin/weixinAuth', params)
        .then(res => {
          Loading.hide();
          if (res.data.code === '000000' || res.data.code === '000001') {
            resolve(res.data);
          } else {
            reject(new Error(res.data.msg));
          }
        })
        .catch(reason => {
          Loading.hide();
          Dialog.alert({
            title: '错误',
            content: reason.message
          });
        });
    });
  },
  [GET_CAPTCHA](context, params) {
    // 获取验证码
    let data = {};
    Object.assign(data, params);
    data.user_phone = encryptByDESModeEBC(params.user_phone);
    return new Promise((resolve, reject) => {
      Loading.show();
      http.post('/pakj/common/getMobileCode', data).then(res => {
        Loading.hide();
        if (res.data.code === '000000') {
          Toast({
            content: '验证码已发送',
            duration: 3000,
            hasMask: true
          });
          context.commit(GET_CAPTCHA_SUCCESS, res.data.data);
          resolve([GET_CAPTCHA_SUCCESS, res.data.data]);
        } else if (res.data.code === '404405') {
          resolve([GET_CAPTCHA_FAILED, res.data.msg]);
        } else {
          Dialog.alert({
            title: res.data.code,
            content: res.data.msg,
            confirmText: '确定'
          });
          reject(new Error(res.data.code + ':' + res.data.msg));
        }
      });
    });
  },
  [GET_CURRENT_LOCATION](context) {
    return new Promise((resolve, reject) => {
      context.commit('setGpsStatus', GPS_LOCATING);
      if (Utils.getCurrentEnv() === 'wx') {
        getCurrentLocationByWeixin()
          .then(res => {
            context.commit(GET_CURRENT_LOCATION_SUCCESS, res);
            resolve();
          })
          .catch(reason => {
            context.commit('setGpsStatus', GPS_ERROR);
            reject(new Error('无法获取当前位置'));
          });
      } else {
        getPositionByBroswer()
          .then(res => {
            context.commit(GET_CURRENT_LOCATION_SUCCESS, res);
            resolve();
          })
          .catch(reason => {
            context.commit('setGpsStatus', GPS_ERROR);
            reject(reason);
          });
      }
    });
  },
  getUserByPhone(context, phone) {
    return new Promise((resolve, reject) => {
      Loading.show();
      http
        .post('/pakj/passenger/getUserByPhone', {
          user_phone: encryptByDESModeEBC(phone)
        })
        .then(res => {
          Loading.hide();
          if (res.data.code === '000000') {
            if (
              res.data.data.is_reg === '1' ||
              res.data.data.is_login_pwd === '0'
            ) {
              reject(new Error('captcha'));
            } else {
              resolve();
            }
          } else {
            Dialog.alert({
              title: '提示',
              content: res.data.msg,
              confirmText: '确定'
            });
            reject(new Error(res.data.msg));
          }
        });
    });
  },
  getCaptchNew(context, params) {
    return new Promise((resolve, reject) => {
      let data = {};
      Object.assign(data, params);
      if (data.user_phone) {
        data.user_phone = encryptByDESModeEBC(params.user_phone);
      } else {
        return reject(new Error('phone required'));
      }
      Loading.show();
      http
        .post('/pakj/passenger/getCodeByPhone', data)
        .then(res => {
          Loading.hide();
          if (res.data.code === '000000') {
            Toast({
              content: res.data.msg,
              duration: 3000,
              position: 'center'
            });
            resolve(res.data.data);
          } else {
            Toast({
              content: res.data.msg,
              duration: 3000,
              position: 'center'
            });
            reject(new Error(res.data.msg));
          }
        })
        .catch(reason => {
          Loading.hide();
          reject(reason);
        });
    });
  },
  checkCaptcha(context, params) {
    return new Promise((resolve, reject) => {
      let data = {};
      Object.assign(data, params);
      if (data.user_phone) {
        data.user_phone = encryptByDESModeEBC(params.user_phone);
      } else {
        return reject(new Error('phone required'));
      }
      Loading.show();
      http
        .post('/pakj/passenger/checkPhoneCode', data)
        .then(res => {
          Loading.hide();
          if (res.data.code === '000000') {
            resolve();
          } else {
            reject(new Error(res.data.msg));
          }
        })
        .catch(reason => {
          Loading.hide();
          reject(new Error(reason));
        });
    });
  },
  getLoginByCode(context, params) {
    return new Promise((resolve, reject) => {
      Loading.show();
      let data = {};
      Object.assign(data, params);
      if (data.user_phone) {
        data.user_phone = encryptByDESModeEBC(params.user_phone);
      } else {
        return reject(new Error('phone required'));
      }
      http.post('/pakj/passenger/getLoginByCode', data).then(res => {
        Loading.hide();
        if (res.data.code === '000000') {
          context.commit(LOGIN_SUCCESS, res.data.data);
          resolve(res.data.data);
        } else if (res.data.code === '200021') {
          // 密码登录未注册
          reject(new Error(res.data.code + ':' + res.data.msg));
        } else if (res.data.code === '100099') {
          // 账号被锁定
          reject(new Error(res.data.code));
          sessionStorage['loginerror'] = res.data.msg;
        } else if (res.data.code === '200020') {
          // 密码登录未设置登录密码
          reject(new Error(res.data.code + ':' + res.data.msg));
        } else if (res.data.code === '200025') {
          Toast({
            content: res.data.msg,
            duration: 3000,
            hasMask: true
          });
          reject(new Error(res.data.msg));
        } else if (res.data.code === '100001') {
          Toast({
            content: res.data.msg,
            duration: 3000,
            hasMask: true
          });
          reject(new Error(res.data.msg));
        } else {
          Dialog.alert({
            title: '提示',
            content: res.data.msg,
            confirmText: '确定'
          });
          reject(new Error(res.data.code + ':' + res.data.msg));
        }
      });
    });
  },
  getLoginByPwd(context, params) {
    return new Promise((resolve, reject) => {
      Loading.show();
      let data = {};
      Object.assign(data, params);
      if (data.user_phone) {
        data.user_phone = encryptByDESModeEBC(params.user_phone);
      } else {
        return reject(new Error('phone required'));
      }
      if (data.user_pwd) {
        data.user_pwd = CryptoJS.MD5(data.user_pwd).toString();
      }
      http.post('/pakj/passenger/getLoginByPwd', data).then(res => {
        Loading.hide();
        if (res.data.code === '000000') {
          context.commit(LOGIN_SUCCESS, res.data.data);
          resolve(res.data.data);
        } else if (res.data.code === '200021') {
          // 密码登录未注册
          reject(new Error(res.data.code + ':' + res.data.msg));
        } else if (res.data.code === '100099') {
          // 账号被锁定
          reject(new Error(res.data.code));
          sessionStorage['loginerror'] = res.data.msg;
        } else if (res.data.code === '200020') {
          // 密码登录未设置登录密码
          reject(new Error(res.data.code + ':' + res.data.msg));
        } else if (res.data.code === '200025') {
          Toast({
            content: res.data.msg,
            duration: 3000,
            hasMask: true
          });
          reject(new Error(res.data.msg));
        } else if (res.data.code === '100001') {
          Toast({
            content: res.data.msg,
            duration: 3000,
            hasMask: true
          });
          reject(new Error(res.data.msg));
        } else {
          Dialog.alert({
            title: '提示',
            content: res.data.msg,
            confirmText: '确定'
          });
          reject(new Error(res.data.code + ':' + res.data.msg));
        }
      });
    });
  },
  changeLoginPassword(context, params) {
    return new Promise((resolve, reject) => {
      Loading.show();
      http
        .post('/pakj/passenger/updateLoginPwd', params)
        .then(res => {
          Loading.hide();
          if (res.data.code === '000000') {
            resolve();
          } else {
            reject(new Error(res.data.msg));
          }
        })
        .catch(reason => {
          Loading.hide();
          reject(reason);
        });
    });
  },
  changeLoginPassword2(context, params) {
    return new Promise((resolve, reject) => {
      Loading.show();
      http
        .post('/pakj/passenger/retrievePwd', params)
        .then(res => {
          Loading.hide();
          if (res.data.code === '000000') {
            resolve();
          } else {
            reject(new Error(res.data.msg));
          }
        })
        .catch(reason => {
          Loading.hide();
          reject(reason);
        });
    });
  },
  changePayPassword(context, params) {
    return new Promise((resolve, reject) => {
      Loading.show();
      http
        .post('/pakj/passenger/updatePayPwd', params)
        .then(res => {
          Loading.hide();
          if (res.data.code === '000000') {
            resolve();
          } else {
            reject(new Error(res.data.msg));
          }
        })
        .catch(reason => {
          Loading.hide();
          reject(reason);
        });
    });
  },
  changePayPassword2(context, params) {
    return new Promise((resolve, reject) => {
      Loading.show();
      http
        .post('/pakj/passenger/retrievePayPwd', params)
        .then(res => {
          Loading.hide();
          if (res.data.code === '000000') {
            resolve();
          } else {
            reject(new Error(res.data.msg));
          }
        })
        .catch(reason => {
          Loading.hide();
          reject(reason);
        });
    });
  }
};

function getPositionByBroswer() {
  return new Promise((resolve, reject) => {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
        position => {
          console.log('通过浏览器获取了位置坐标：', position);
          getPositionDetail(position.coords)
            .then(result => {
              resolve(result);
            })
            .catch(reason => {
              reject(reason);
            });
        },
        error => {
          reject(error);
        }
      );
    } else {
      reject(new Error('当前浏览器没有定位权限'));
    }
  });
}

function getPositionDetail(coords) {
  return new Promise((resolve, reject) => {
    AMap.plugin('AMap.Geocoder', function() {
      var geocoder = new AMap.Geocoder({});
      var lnglat = [coords.longitude, coords.latitude];
      geocoder.getAddress(lnglat, function(status, result) {
        if (status === 'complete' && result.info === 'OK') {
          let detail = result.regeocode.addressComponent;
          if (detail) {
            let city = detail.city;
            if (city === '') {
              city = detail.province;
            }
            let adcode = {
              provinceCode: detail.adcode,
              provinceName: detail.district,
              coordinate: lnglat,
              address: result.regeocode.formattedAddress,
              city: city
            };
            resolve(adcode);
          } else {
            reject(new Error('当前浏览器没有定位权限'));
          }
        } else {
          reject(new Error('高德地图位置信息获取失败'));
        }
      });
    });
  });
}

function getCurrentLocationByBroswer() {
  return new Promise((resolve, reject) => {
    getPositionByBroswer()
      .then(position => {
        getPositionDetail(position)
          .then(result => {
            resolve(result);
          })
          .catch(reason => {
            reject(reason);
          });
      })
      .catch(reason => {
        reject(reason);
      });
  });
}

function getCurrentLocationByWeixin() {
  return new Promise((resolve, reject) => {
    weixin.wxConfig(['getLocation']).then(() => {
      weixin
        .getCurrentLocation()
        .then(res => {
          getPositionDetail(res)
            .then(result => {
              resolve(result);
            })
            .catch(reason => {
              reject(reason);
            });
        })
        .catch(reason => {
          reject(reason);
        });
    });
  });
}

function getCurrentLocationByAMap() {
  return new Promise((resolve, reject) => {
    Loading.show();
    AMap.plugin('AMap.Geolocation', function() {
      // 异步加载插件
      var geolocation = new AMap.Geolocation({
        // 是否使用高精度定位，默认：true
        enableHighAccuracy: true,
        // 设置定位超时时间，默认：无穷大
        timeout: 5000,
        convert: true
      });
      if (geolocation.isSupported()) {
        geolocation.getCurrentPosition((status, result) => {
          Loading.hide();
          if (status === 'complete') {
            if (result.addressComponent) {
              let adcode = {
                provinceCode: result.addressComponent.adcode,
                provinceName: result.addressComponent.district,
                coordinate: [result.position.lng, result.position.lat],
                address: result.formattedAddress
              };
              resolve(adcode);
            } else {
              console.log(status);
              reject(new Error('高德定位获取位置信息失败'));
            }
          } else {
            reject(new Error('当前浏览器没有定位权限'));
          }
        });
      } else {
        Loading.hide();
        reject(new Error('浏览器不支持定位功能，无法获取用户当前位置'));
      }
    });
  });
}
const mutations = {
  resetUser(state) {
    Object.assign(state, defaultState());
  },
  [SET_PLATFORM_ID](state, id) {
    console.log('发现商户ID：', id);
    state.platformId = id;
  },
  [LOGIN_SUCCESS](state, user) {
    user.user_phone = decryptByDESModeEBC(user.user_phone);
    state.user = user;
    state.token = user.token;
    state.isLogin = true;
    let jsonStr = JSON.stringify(user);
    localStorage.setItem('USER_INFO', jsonStr);
    if (user.user_headpath) {
      let userHeadpathUrl =
        Config.ossImgUrl + user.user_headpath.replace(/^http:\/\//, 'https://');
      localStorage.setItem('user_headpath', userHeadpathUrl);
    }
    localStorage.setItem('nick_name', user.nick_name);
    localStorage.setItem('is_identity', user.is_identity);
  },
  [GET_CAPTCHA_SUCCESS](state, captcha) {
    state.captcha = captcha;
  },
  sethitchDriverLoginInfo(state, user) {
    user.user_phone = decryptByDESModeEBC(user.user_phone);
    state.user = user;
    state.token = user.token;
    state.isLogin = true;
    let jsonStr = JSON.stringify(user);
    localStorage.setItem('USER_INFO', jsonStr);
  },
  setToken(state, token) {
    console.log('SET_TOKEN:', token);
    state.token = token;
  },
  setOpenId(state, id) {
    console.log('OPEN_ID:', id);
    state.openId = id;
  },
  setUnionId(state, id) {
    console.log('UNION_ID:', id);
    state.unionId = id;
  },
  setCurrentPhone(state, phone) {
    state.phone = phone;
  },
  [GET_CURRENT_LOCATION_SUCCESS](state, result) {
    console.info('成功获取当前用户位置：', result);
    state.currentLocation = result;
    state.gpsStatus = GPS_SUCCESS;
  },
  setGpsStatus(state, status) {
    state.gpsStatus = status;
  },
  setLoginMode(state, mode) {
    state.loginMode = mode;
  }
};
export default {
  state,
  actions,
  getters,
  mutations
};
